package com.obj.commpont.common.captcha;

import com.obj.commpont.common.captcha.util.CaptchaRandomUtils;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.OutputStream;

/**
 * 简单的图片验证码生成工具类
 *
 * @author yuan 2018/12/3 14:27
 */
public class CaptchaUtils {

    /**
     * 生成指定大小，图片格式的图形验证码
     *
     * @param width     宽度
     * @param height    高度
     * @param imageType 图片格式
     * @return 输出图片
     **/
    public static void createCaptchaImage(int width, int height, String captchaCode, String imageType, OutputStream outputStream) {
        try {
            ImageIO.write(createImage(width, height, captchaCode), imageType, outputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 生成图片验证码
     *
     * @param width       宽度
     * @param height      高度
     * @param captchaCode 指定字符串
     * @return 图片流
     **/
    private static BufferedImage createImage(int width, int height, String captchaCode) {
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        Graphics2D g2 = image.createGraphics();
        //抗锯齿
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        //设置背景色
        g2.setColor(new Color(255, 255, 255));
        g2.fillRect(0, 0, width, height);
        //绘制干扰线
        drawLine(8, null, g2, width, height);
        //绘制干扰圈
        drawOval(8, g2, width, height);
        //指定透明度
        AlphaComposite ac3 = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.8f);
        g2.setComposite(ac3);
        //验证码长度
        int codeLength = captchaCode.length();
        //字体大小
        int fontSize = 24;
        int hp = (height - fontSize) >> 1;
        int h = height - hp;
        int w = width / codeLength;
        int sp = (w - fontSize) / 2;
        //字体
        Font font = new Font("Arial", Font.BOLD, fontSize);
        char[] chars = captchaCode.toCharArray();
        for (int i = 0; i < codeLength; i++) {
            g2.setColor(CaptchaRandomUtils.getRundomRgb(40, 180));
            int x = i * w + sp + CaptchaRandomUtils.randomNum(3);
            int y = h - CaptchaRandomUtils.randomNum(3, 6);
            if (x < 8) {
                x = 8;
            }
            if (x + font.getSize() > width) {
                x = width - font.getSize();
            }
            if (y > height) {
                y = height;
            }
            if (y - font.getSize() < 0) {
                y = font.getSize();
            }
            g2.setFont(font.deriveFont(CaptchaRandomUtils.randomNum(2) == 0 ? Font.PLAIN : Font.ITALIC));
            g2.drawString(String.valueOf(chars[i]), x, y);
        }
        g2.dispose();
        return image;
    }

    /**
     * 随机画干扰线
     *
     * @param num   数量
     * @param color 颜色
     * @param g     Graphics2D
     */
    public static void drawLine(int num, Color color, Graphics2D g, int width, int height) {
        for (int i = 0; i < num; i++) {
            g.setColor(color == null ? CaptchaRandomUtils.getRundomRgb(150, 250) : color);
            int x1 = CaptchaRandomUtils.randomNum(-10, width - 10);
            int y1 = CaptchaRandomUtils.randomNum(5, height - 5);
            int x2 = CaptchaRandomUtils.randomNum(10, width + 10);
            int y2 = CaptchaRandomUtils.randomNum(2, height - 2);
            g.drawLine(x1, y1, x2, y2);
        }
    }

    /**
     * 随机画干扰圆
     *
     * @param num 数量
     * @param g   Graphics2D
     */
    public static void drawOval(int num, Graphics2D g, int width, int height) {
        for (int i = 0; i < num; i++) {
            g.setColor(CaptchaRandomUtils.getRundomRgb(100, 250));
            g.drawOval(CaptchaRandomUtils.randomNum(width), CaptchaRandomUtils.randomNum(height), 10 + CaptchaRandomUtils.randomNum(20), 10 + CaptchaRandomUtils.randomNum(20));
        }
    }
}
